package org.example.atomictest;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
 * @author zhengdp
 * @Description 原子累加器测试
 * @Date 2022/11/20 19:50
 * @Created by zhengdp
 */
public class LongAddrTest {
    public static void main(String[] args) {
        System.out.println("======== 原子整数累加测试 ==========");
        for (int i = 0; i < 5; i++) {
            demo(
                    () -> new AtomicLong(0),
                    AtomicLong::getAndIncrement
            );
        }

        System.out.println("========== 原子累加器测试 ===========");
        for (int i = 0; i < 5; i++) {
            demo(
                    LongAdder::new,
                    LongAdder::increment
            );
        }
    }

    private static <T> void demo (Supplier<T> supplier, Consumer<T> consumer){
        T array = supplier.get();

        long start = System.nanoTime();

        List<Thread> ts = new ArrayList<>();

        // 4个线程，每人累加50w
        for ( int i = 0; i< 4; i ++) {
            ts.add(new Thread(() -> {
                for ( int j = 0; j < 500000;j++) {
                    consumer.accept(array);
                }
            }));
        }
        ts.forEach(Thread::start);
        ts.forEach(t -> {
            try {
                t.join();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        long end = System.nanoTime();
        System.out.println(array + " cost : "+ (end - start ) / 1000_000);
    }

}
